﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Windows;//--------------,
using System.Windows.Input;//? <-----|
using System.Windows.Controls;//? <--'

using ZOIL.DataModel;
using ZOIL.Framework.Presentation;
using ZOIL.Library.Devices.OSC;// Was ist denn das?

using Microsoft.Surface.Presentation.Controls;
using System.Windows.Ink;
using System.IO;
using System.Collections.Specialized;

namespace ZOIL.Library.Components//Library.Components.ViPostIt
{
    [ViewModelFor(typeof(ViPostItView))]//GRAH
    public class ViPostItViewModel : BaseViewModel
    {
        private StrokeCollection _strokes;
        private List<Stroke> _mostRecentStrokes;

        public ViPostItViewModel()
            : base()
        {
            //RegisterChangeNotifications
           // RegisterChangeNotification("Id", "Id");
            RegisterChangeNotification("PageID", "PageID");
            RegisterChangeNotification("SmallUrl", "SmallUrl");
            RegisterChangeNotification("Title", "Title");
            RegisterChangeNotification("MyStrokes", "MyStrokes");



            //ZoomCommand
            ZoomCommand = new RoutedCommand("ZoomCommand", typeof(ViPostItViewModel));
            CommandBinding binding = new CommandBinding(ZoomCommand, ExecuteZoomCommand, CanExecuteZoomCommand);
            this.CommandBindings.Add(binding);

        }

        public new ViPostIt Model
        {
            get
            {
                return base.Model as ViPostIt;
            }
            set
            {
                base.Model = value;
            }
        }

        #region Properties

        //public Int32 Id
        //{
        //    get
        //    {
        //        return new Int32((Model as ViPostIt).Id);
        //    }
        //    set
        //    {
        //        (Model as ViPostIt).Id = value;
        //        RaisePropertyChangedEvent("Id");
        //    }
        //}
        public int? PageID
        {
            get
            {
                return ((Model as ViPostIt).PageID);
            }
            set
            {
                (Model as ViPostIt).PageID = value;
                RaisePropertyChangedEvent("PageID");
            }
        }


        public Uri SmallUrl
        {
            get
            {

                return new Uri((Model as ViPostIt).SmallUrl.ToString());
            }
            set
            {
                (Model as ViPostIt).SmallUrl = value;
                RaisePropertyChangedEvent("SmallUrl");
            }
        }
        public String Title
        {
            get
            {
                return (Model as ViPostIt).Title;
            }
            set
            {
                (Model as ViPostIt).Title = value;
                RaisePropertyChangedEvent("Title");
            }
        }

        public StrokeCollection MyStrokes
        {
            get
            {
                if (_strokes == null)
                {
                    refreshStrokes();
                    (Model as ViPostIt).PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(ViPostItViewModel_PropertyChanged);
                }
                return _strokes;
            }
        }

        private void refreshStrokes()
        {
            if ((Model as ViPostIt).MyStrokes != null)
            {
                MemoryStream ms = new MemoryStream(Convert.FromBase64String((Model as ViPostIt).MyStrokes));
                _strokes = new StrokeCollection(ms);
            }
            else
            {
                _strokes = new StrokeCollection();
            }

            (_strokes as INotifyCollectionChanged).CollectionChanged += OnStrokeCollectionChanged;
        }

        void ViPostItViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName.Equals("MyStrokes"))
            {
                refreshStrokes();
                RaisePropertyChangedEvent("MyStrokes");
            }
        }

        public void OnStrokeCollected(object sender, InkCanvasStrokeCollectedEventArgs e)
        {
            _mostRecentStrokes.Add(e.Stroke);
        }

        private void OnStrokeCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if ((View as ViPostItView).DrawingPadCanvas.getIsDrawing())
            {
                //do nothing while dynamic change!
            }
            else
            {

                //if you take _strokes here, they are not getting updated
                //so take the strokes from the event and update the _strokes in the
                //refreshStrokes method (JS)
                StrokeCollection realStrokes = sender as StrokeCollection;

                if (realStrokes != null)
                {
                    StrokeCollection clonedStrokes = realStrokes.Clone();
                    MemoryStream base64Ink = new MemoryStream();
                    clonedStrokes.Save(base64Ink);
                    String strokes = Convert.ToBase64String(base64Ink.ToArray());
                    (Model as ViPostIt).MyStrokes = strokes;
                }
                RaisePropertyChangedEvent("MyStrokes");
            }

        }

        #endregion

        #region Commands

        #region ZoomCommand
        //WTF Part

        private RoutedCommand _zoomCoomand;
        public RoutedCommand ZoomCommand
        {
            get
            {
                return _zoomCoomand;
            }
            set
            {
                _zoomCoomand = value;
                RaisePropertyChangedEvent("ZoomCommand");
            }
        }

        private void ExecuteZoomCommand(object sender, ExecutedRoutedEventArgs e)
        {
            String oscAdress = "none";
            int cubePort = 0;

            #region identify cube

            SurfaceButton b = e.OriginalSource as SurfaceButton;
            if (b != null)
            {
                if (b.Name == "Cube1Button")
                {
                    oscAdress = "/cube1/landscape";
                    cubePort = 1;
                }
                else if (b.Name == "Cube2Button")
                {
                    oscAdress = "/cube2/landscape";
                    cubePort = 2;
                }
            }
            #endregion

             //identify the clicked Element
            FrameworkElement target = this.View as FrameworkElement;
            if (target != null)
            {
                //identify the next zoom target in the visual tree
                target = ZTreeHelper.GetClosestZoomTarget(target);
                Panel.SetZIndex(target, ZComponent.ZIndexCounter++);

                //get landscape to calculate the bounds of the viewports
                ZInformationLandscape zil = ZTreeHelper.TryFindParent<ZInformationLandscape>(target);
                if (zil == null)
                {
                    return;
                }
                Rect rect = zil.getControlPositionInLandcape(target);

                //send the calculated rectangle via OSC to the cube (part of the multicast group)
                OSCSender.sendZoomCommand(System.Net.IPAddress.Parse("224.5.6.7"), oscAdress , 4497 + cubePort,
                    rect.X,
                    rect.Y,
                    rect.Width,
                    rect.Height, 1);
            }

        }

        private void CanExecuteZoomCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        #endregion

        #endregion

    }
}
